home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / kangaroo.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  10KB  |  350 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ***************************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "vidhrdw/generic.h"
  11.  
  12.  
  13. unsigned char *kangaroo_video_control;
  14. unsigned char *kangaroo_bank_select;
  15. unsigned char *kangaroo_blitter;
  16. unsigned char *kangaroo_scroll;
  17.  
  18. static int screen_flipped;
  19. static struct osd_bitmap *tmpbitmap2;
  20.  
  21.  
  22. /***************************************************************************
  23.  
  24.   Convert the color PROMs into a more useable format.
  25.  
  26.   Kangaroo doesn't have color PROMs, the playfield data is directly converted
  27.   into colors: 1 bit per gun, therefore only 8 possible colors, but there is
  28.   also a global mask register which controls intensities of the three guns,
  29.   separately for foreground and background. The fourth bit in the video RAM
  30.   data disables this mask, making the color display at full intensity
  31.   regardless of the mask value.
  32.   Actually the mask doesn't directly control intensity. The guns are rapidly
  33.   turned on and off at a subpixel rate, relying on the monitor to blend the
  34.   colors into a more or less uniform half intensity color.
  35.  
  36.   We use three groups of 8 pens: the first is fixed and contains the 8
  37.   possible colors; the other two are dynamically modified when the mask
  38.   register is written to, one is for the background, the other for sprites.
  39.  
  40. ***************************************************************************/
  41.  
  42. void kangaroo_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  43. {
  44.     int i;
  45.  
  46.  
  47.     for (i = 0;i < Machine->drv->total_colors;i++)
  48.     {
  49.         *(palette++) = ((i & 4) >> 2) * 0xff;
  50.         *(palette++) = ((i & 2) >> 1) * 0xff;
  51.         *(palette++) = ((i & 1) >> 0) * 0xff;
  52.     }
  53. }
  54.  
  55.  
  56.  
  57. /***************************************************************************
  58.  
  59.   Start the video hardware emulation.
  60.  
  61. ***************************************************************************/
  62.  
  63. int kangaroo_vh_start(void)
  64. {
  65.     if ((tmpbitmap = osd_create_bitmap(Machine->drv->screen_width,Machine->drv->screen_height)) == 0)
  66.         return 1;
  67.  
  68.     if ((tmpbitmap2 = osd_create_bitmap(Machine->drv->screen_width,Machine->drv->screen_height)) == 0)
  69.     {
  70.         osd_free_bitmap(tmpbitmap);
  71.         return 1;
  72.     }
  73.  
  74.     if ((videoram = malloc(Machine->drv->screen_width*Machine->drv->screen_height)) == 0)
  75.     {
  76.         osd_free_bitmap(tmpbitmap);
  77.         osd_free_bitmap(tmpbitmap2);
  78.     }
  79.  
  80.     return 0;
  81. }
  82.  
  83.  
  84.  
  85. /***************************************************************************
  86.  
  87.   Stop the video hardware emulation.
  88.  
  89. ***************************************************************************/
  90.  
  91. void kangaroo_vh_stop(void)
  92. {
  93.     osd_free_bitmap(tmpbitmap2);
  94.     osd_free_bitmap(tmpbitmap);
  95.     free(videoram);
  96. }
  97.  
  98.  
  99. WRITE_HANDLER( kangaroo_video_control_w )
  100. {
  101.     /* A & B bitmap control latch (A=playfield B=motion)
  102.           bit 5 FLIP A
  103.           bit 4 FLIP B
  104.           bit 3 EN A
  105.           bit 2 EN B
  106.           bit 1 PRI A
  107.           bit 0 PRI B */
  108.  
  109.     if ((*kangaroo_video_control & 0x30) != (data & 0x30))
  110.     {
  111.         screen_flipped = 1;
  112.     }
  113.  
  114.     *kangaroo_video_control = data;
  115. }
  116.  
  117.  
  118. WRITE_HANDLER( kangaroo_bank_select_w )
  119. {
  120.     unsigned char *RAM = memory_region(REGION_CPU1);
  121.  
  122.  
  123.     /* this is a VERY crude way to handle the banked ROMs - but it's */
  124.     /* correct enough to pass the self test */
  125.     if (data & 0x05)
  126.         cpu_setbank(1,&RAM[0x10000])
  127.     else
  128.         cpu_setbank(1,&RAM[0x12000]);
  129.  
  130.     *kangaroo_bank_select = data;
  131. }
  132.  
  133.  
  134.  
  135. WRITE_HANDLER( kangaroo_color_mask_w )
  136. {
  137.     int i;
  138.  
  139.  
  140.     /* color mask for A plane */
  141.     for (i = 0;i < 8;i++)
  142.     {
  143.         int r,g,b;
  144.  
  145.  
  146.         r = ((i & 4) >> 2) * ((data & 0x20) ? 0xff : 0x7f);
  147.         g = ((i & 2) >> 1) * ((data & 0x10) ? 0xff : 0x7f);
  148.         b = ((i & 1) >> 0) * ((data & 0x08) ? 0xff : 0x7f);
  149.  
  150.         palette_change_color(8+i,r,g,b);
  151.     }
  152.  
  153.     /* color mask for B plane */
  154.     for (i = 0;i < 8;i++)
  155.     {
  156.         int r,g,b;
  157.  
  158.  
  159.         r = ((i & 4) >> 2) * ((data & 0x04) ? 0xff : 0x7f);
  160.         g = ((i & 2) >> 1) * ((data & 0x02) ? 0xff : 0x7f);
  161.         b = ((i & 1) >> 0) * ((data & 0x01) ? 0xff : 0x7f);
  162.  
  163.         palette_change_color(16+i,r,g,b);
  164.     }
  165. }
  166.  
  167.  
  168.  
  169. WRITE_HANDLER( kangaroo_blitter_w )
  170. {
  171.     kangaroo_blitter[offset] = data;
  172.  
  173.     if (offset == 5)    /* trigger DMA */
  174.     {
  175.         int src,dest;
  176.         int x,y,xb,yb,old_bank_select,new_bank_select;
  177.  
  178.         src = kangaroo_blitter[0] + 256 * kangaroo_blitter[1];
  179.         dest = kangaroo_blitter[2] + 256 * kangaroo_blitter[3];
  180.  
  181.         xb = kangaroo_blitter[5];
  182.         yb = kangaroo_blitter[4];
  183.  
  184.         old_bank_select = new_bank_select = *kangaroo_bank_select;
  185.  
  186.         if (new_bank_select & 0x0c)  new_bank_select |= 0x0c;
  187.         if (new_bank_select & 0x03)  new_bank_select |= 0x03;
  188.         kangaroo_bank_select_w(0, new_bank_select & 0x05);
  189.  
  190.         for (x = 0;x <= xb;x++)
  191.         {
  192.             for (y = 0;y <= yb;y++)
  193.             {
  194.                 cpu_writemem16(dest++, cpu_readmem16(src++));
  195.             }
  196.  
  197.             dest = dest - (yb + 1) + 256;
  198.         }
  199.  
  200.         src = kangaroo_blitter[0] + 256 * kangaroo_blitter[1];
  201.         dest = kangaroo_blitter[2] + 256 * kangaroo_blitter[3];
  202.  
  203.         kangaroo_bank_select_w(0, new_bank_select & 0x0a);
  204.  
  205.         for (x = 0;x <= xb;x++)
  206.         {
  207.             for (y = 0;y <= yb;y++)
  208.             {
  209.                 cpu_writemem16(dest++, cpu_readmem16(src++));
  210.             }
  211.  
  212.             dest = dest - (yb + 1) + 256;
  213.         }
  214.  
  215.         kangaroo_bank_select_w(0, old_bank_select);
  216.     }
  217. }
  218.  
  219.  
  220.  
  221. INLINE void kangaroo_plot_pixel(struct osd_bitmap *bitmap, int x, int y, int col, int color_base, int flip)
  222. {
  223.     if (flip)
  224.     {
  225.         x = bitmap->width - 1 - x;
  226.         y = bitmap->height - 1 - y;
  227.     }
  228.  
  229.     plot_pixel(bitmap, x, y, Machine->pens[((col & 0x08) ? 0 : color_base) + (col & 0x07)]);
  230. }
  231.  
  232. INLINE void kangaroo_redraw_4pixels(int x, int y)
  233. {
  234.     int offs, flipA, flipB;
  235.  
  236.  
  237.     offs = y * 256 + x;
  238.  
  239.     flipA = *kangaroo_video_control & 0x20;
  240.     flipB = *kangaroo_video_control & 0x10;
  241.  
  242.     kangaroo_plot_pixel(tmpbitmap , x  , y, videoram[offs  ] & 0x0f, 8,  flipA);
  243.     kangaroo_plot_pixel(tmpbitmap , x+1, y, videoram[offs+1] & 0x0f, 8,  flipA);
  244.     kangaroo_plot_pixel(tmpbitmap , x+2, y, videoram[offs+2] & 0x0f, 8,  flipA);
  245.     kangaroo_plot_pixel(tmpbitmap , x+3, y, videoram[offs+3] & 0x0f, 8,  flipA);
  246.     kangaroo_plot_pixel(tmpbitmap2, x  , y, videoram[offs  ] >> 4,   16, flipB);
  247.     kangaroo_plot_pixel(tmpbitmap2, x+1, y, videoram[offs+1] >> 4,   16, flipB);
  248.     kangaroo_plot_pixel(tmpbitmap2, x+2, y, videoram[offs+2] >> 4,   16, flipB);
  249.     kangaroo_plot_pixel(tmpbitmap2, x+3, y, videoram[offs+3] >> 4,   16, flipB);
  250. }
  251.  
  252. WRITE_HANDLER( kangaroo_videoram_w )
  253. {
  254.     int a_Z_R,a_G_B,b_Z_R,b_G_B;
  255.     int sx, sy, offs;
  256.  
  257.     a_Z_R = *kangaroo_bank_select & 0x01;
  258.     a_G_B = *kangaroo_bank_select & 0x02;
  259.     b_Z_R = *kangaroo_bank_select & 0x04;
  260.     b_G_B = *kangaroo_bank_select & 0x08;
  261.  
  262.  
  263.     sx = (offset / 256) * 4;
  264.     sy = offset % 256;
  265.     offs = sy * 256 + sx;
  266.  
  267.     if (a_G_B)
  268.     {
  269.         videoram[offs  ] = (videoram[offs  ] & 0xfc) | ((data & 0x10) >> 3) | ((data & 0x01) >> 0);
  270.         videoram[offs+1] = (videoram[offs+1] & 0xfc) | ((data & 0x20) >> 4) | ((data & 0x02) >> 1);
  271.         videoram[offs+2] = (videoram[offs+2] & 0xfc) | ((data & 0x40) >> 5) | ((data & 0x04) >> 2);
  272.         videoram[offs+3] = (videoram[offs+3] & 0xfc) | ((data & 0x80) >> 6) | ((data & 0x08) >> 3);
  273.     }
  274.  
  275.     if (a_Z_R)
  276.     {
  277.         videoram[offs  ] = (videoram[offs  ] & 0xf3) | ((data & 0x10) >> 1) | ((data & 0x01) << 2);
  278.         videoram[offs+1] = (videoram[offs+1] & 0xf3) | ((data & 0x20) >> 2) | ((data & 0x02) << 1);
  279.         videoram[offs+2] = (videoram[offs+2] & 0xf3) | ((data & 0x40) >> 3) | ((data & 0x04) >> 0);
  280.         videoram[offs+3] = (videoram[offs+3] & 0xf3) | ((data & 0x80) >> 4) | ((data & 0x08) >> 1);
  281.     }
  282.  
  283.     if (b_G_B)
  284.     {
  285.         videoram[offs  ] = (videoram[offs  ] & 0xcf) | ((data & 0x10) << 1) | ((data & 0x01) << 4);
  286.         videoram[offs+1] = (videoram[offs+1] & 0xcf) | ((data & 0x20) >> 0) | ((data & 0x02) << 3);
  287.         videoram[offs+2] = (videoram[offs+2] & 0xcf) | ((data & 0x40) >> 1) | ((data & 0x04) << 2);
  288.         videoram[offs+3] = (videoram[offs+3] & 0xcf) | ((data & 0x80) >> 2) | ((data & 0x08) << 1);
  289.     }
  290.  
  291.     if (b_Z_R)
  292.     {
  293.         videoram[offs  ] = (videoram[offs  ] & 0x3f) | ((data & 0x10) << 3) | ((data & 0x01) << 6);
  294.         videoram[offs+1] = (videoram[offs+1] & 0x3f) | ((data & 0x20) << 2) | ((data & 0x02) << 5);
  295.         videoram[offs+2] = (videoram[offs+2] & 0x3f) | ((data & 0x40) << 1) | ((data & 0x04) << 4);
  296.         videoram[offs+3] = (videoram[offs+3] & 0x3f) | ((data & 0x80) << 0) | ((data & 0x08) << 3);
  297.     }
  298.  
  299.     kangaroo_redraw_4pixels(sx, sy);
  300. }
  301.  
  302.  
  303.  
  304. /***************************************************************************
  305.  
  306.   Draw the game screen in the given osd_bitmap.
  307.   Do NOT call osd_update_display() from this function, it will be called by
  308.   the main emulation engine.
  309.  
  310. ***************************************************************************/
  311.  
  312. void kangaroo_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  313. {
  314.     int scrollx, scrolly;
  315.  
  316.  
  317.     if (palette_recalc() || screen_flipped)
  318.     {
  319.         int x, y;
  320.  
  321.         /* redraw bitmap */
  322.         for (x = 0; x < 256; x+=4)
  323.         {
  324.             for (y = 0; y < 256; y++)
  325.             {
  326.                 kangaroo_redraw_4pixels(x, y);
  327.             }
  328.         }
  329.  
  330.         screen_flipped = 0;
  331.     }
  332.  
  333.  
  334.     scrollx = kangaroo_scroll[1];
  335.     scrolly = kangaroo_scroll[0];
  336.  
  337.     if (*kangaroo_bank_select & 0x01)
  338.     {
  339.         /* Plane B is primary */
  340.         copybitmap(bitmap,tmpbitmap2,0,0,0,0,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  341.         copyscrollbitmap(bitmap,tmpbitmap,1,&scrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_COLOR,8);
  342.     }
  343.     else
  344.     {
  345.         /* Plane A is primary */
  346.         copyscrollbitmap(bitmap,tmpbitmap,1,&scrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  347.         copybitmap(bitmap,tmpbitmap2,0,0,0,0,&Machine->drv->visible_area,TRANSPARENCY_COLOR,16);
  348.     }
  349. }
  350.